home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / Draw / Sources / DrawView.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  15.2 KB  |  569 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                DrawView.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "ODFDraw.hpp"
  11.  
  12. #ifndef DRAWVIEW_H
  13. #include "DrawView.h"
  14. #endif
  15.  
  16. #ifndef DEFINES_K
  17. #include "Defines.k"
  18. #endif
  19.  
  20. #ifndef DRAWPART_H
  21. #include "DrawPart.h"
  22. #endif
  23.  
  24. #ifndef DRAWFRM_H
  25. #include "DrawFrm.h"
  26. #endif
  27.  
  28. #ifndef DRAWSEL_H
  29. #include "DrawSel.h"
  30. #endif
  31.  
  32. #ifndef BASESHP_H
  33. #include "BaseShp.h"
  34. #endif
  35.  
  36. #ifndef BOUNDSHP_H
  37. #include "BoundShp.h"
  38. #endif
  39.  
  40. #ifndef LINESHP_H
  41. #include "LineShp.h"
  42. #endif
  43.  
  44. #ifndef OVALSHP_H
  45. #include "OvalShp.h"
  46. #endif
  47.  
  48. #ifndef RECTSHP_H
  49. #include "RectShp.h"
  50. #endif
  51.  
  52. #ifndef RRECTSHP_H
  53. #include "RRectShp.h"
  54. #endif
  55.  
  56. #ifndef TEXTSHP_H
  57. #include "TextShp.h"
  58. #endif
  59.  
  60. #ifndef DRAWPRXY_H
  61. #include "DrawPrxy.h"
  62. #endif
  63.  
  64. #ifndef SHPTRAKR_H
  65. #include "ShpTrakr.h"
  66. #endif
  67.  
  68. #ifndef DRAWCMDS_H
  69. #include "DrawCmds.h"
  70. #endif
  71.  
  72. #ifndef DRAWCLIP_H
  73. #include "DrawClip.h"
  74. #endif
  75.  
  76. #ifndef UTILS_H
  77. #include "Utils.h"
  78. #endif
  79.  
  80. #ifndef DRWDDCMD_H
  81. #include "DrwDDCmd.h"
  82. #endif
  83.  
  84. #ifndef DRAWCONT_H
  85. #include "DrawCont.h"
  86. #endif
  87.  
  88. // ----- Framework Layer -----
  89.  
  90. #ifndef FWUTIL_H
  91. #include "FWUtil.h"
  92. #endif
  93.  
  94. #ifndef FWEVEDEF_H
  95. #include "FWEveDef.h"
  96. #endif
  97.  
  98. #ifndef FWPRESEN_H
  99. #include "FWPresen.h"
  100. #endif
  101.  
  102. #ifndef FWSCROLR_H
  103. #include "FWScrolr.h"
  104. #endif
  105.  
  106. #ifndef FWSCLBAR_H
  107. #include "FWSclBar.h"
  108. #endif
  109.  
  110. #ifndef FWGROWBX_H
  111. #include "FWGrowBx.h"
  112. #endif
  113.  
  114. #ifndef FWCONTXT_H
  115. #include "FWContxt.h"
  116. #endif
  117.  
  118. #ifndef FWCLPCMD_H
  119. #include "FWClpCmd.h"
  120. #endif
  121.  
  122. // ----- OS Layer -----
  123.  
  124. #ifndef FWMENU_H
  125. #include "FWMenu.h"
  126. #endif
  127.  
  128. #ifndef FWRECSHP_H
  129. #include "FWRecShp.h"
  130. #endif
  131.  
  132. #ifndef FWCURSOR_H
  133. #include "FWCursor.h"
  134. #endif
  135.  
  136. #ifndef FWEVENT_H
  137. #include "FWEvent.h"
  138. #endif
  139.  
  140. #ifndef FWODGEOM_H
  141. #include "FWODGeom.h"
  142. #endif
  143.  
  144. #ifndef FWLINSHP_H
  145. #include "FWLinShp.h"
  146. #endif
  147.  
  148. #ifndef FWBMPSHP_H
  149. #include "FWBmpShp.h"
  150. #endif
  151.  
  152. #ifndef SLMixOS_H
  153. #include "SLMixOS.h"
  154. #endif
  155.  
  156. // ----- OpenDoc Includes -----
  157.  
  158. #ifndef SOM_Module_OpenDoc_Commands_defined
  159. #include <CmdDefs.xh>
  160. #endif
  161.  
  162. #ifndef SOM_Module_OpenDoc_StdProps_defined
  163. #include <StdProps.xh>
  164. #endif
  165.  
  166. #ifndef SOM_ODSession_xh
  167. #include <ODSessn.xh>
  168. #endif
  169.  
  170. #ifndef SOM_ODDispatcher_xh
  171. #include <Disptch.xh>
  172. #endif
  173.  
  174. //========================================================================================
  175. // RunTime Info
  176. //========================================================================================
  177.  
  178. #ifdef FW_BUILD_MAC
  179. #pragma segment odfdrawframes
  180. #endif
  181.  
  182. FW_DEFINE_CLASS_M1(CDrawView, FW_CSuperView)
  183.  
  184. const FW_ClassTypeConstant LDrawView = FW_TYPE_CONSTANT('d','r','v','w');
  185. FW_REGISTER_ARCHIVABLE_CLASS(LDrawView, CDrawView, CDrawView::Create, FW_CView::Read, CDrawView::Destroy, FW_CView::Write)
  186.  
  187. //========================================================================================
  188. // CDrawView
  189. //========================================================================================
  190.  
  191. //----------------------------------------------------------------------------------------
  192. // CDrawView::CDrawView
  193. //----------------------------------------------------------------------------------------
  194.  
  195. CDrawView::CDrawView(Environment* ev) :
  196.     FW_CSuperView(ev),
  197.     fDrawPart(NULL),
  198.     fDrawFrame(NULL),
  199.     fDrawPartContent(NULL)
  200. {    
  201. }
  202.  
  203. //----------------------------------------------------------------------------------------
  204. // CDrawView::~CDrawView
  205. //----------------------------------------------------------------------------------------
  206.  
  207. CDrawView::~CDrawView()
  208. {
  209. }
  210.  
  211. //----------------------------------------------------------------------------------------
  212. // CDrawView::Draw
  213. //----------------------------------------------------------------------------------------
  214.  
  215. void CDrawView::Draw(Environment *ev, ODFacet* odFacet, ODShape* invalidShape)
  216. {
  217.     // Render inside the content view
  218.     FW_CViewContext vc(ev, this, odFacet, invalidShape);
  219.     FW_CRect invalidRect;
  220.     vc.GetClipRect(invalidRect);
  221.  
  222.     FW_CRectShape::RenderRect(vc, invalidRect, FW_kFill, FW_kWhiteEraseInk);
  223.  
  224.     // ----- Determine what to Render -----
  225.     ODCanvas* canvas = odFacet->GetCanvas(ev);
  226.     FW_Boolean dynamicCanvas = canvas->IsDynamic(ev);
  227.  
  228.     if (dynamicCanvas)
  229.     {
  230.         FW_CRectShape::RenderRect(vc, invalidRect, FW_kFill, FW_kRGBWhite);
  231.         DrawGrid(ev, vc, invalidRect);    // Render the grid
  232.     }
  233.  
  234.     // ----- Render every shape -----
  235.     FW_CRect updateBox;
  236.     CDrawContentShapeIterator ite(fDrawPartContent);
  237.     for (CBaseShape* theShape = ite.First(); ite.IsNotComplete(); theShape = ite.Next())
  238.     {
  239.         theShape->GetUpdateBox(updateBox);
  240.         if (invalidRect.IsIntersecting(updateBox))
  241.             theShape->RenderShape(ev, odFacet, vc);
  242.     }
  243.  
  244.     // ----- Render selections Handles -----
  245.     FW_CFrame* frame = GetFrame(ev);
  246.     if (frame->HasSelectionFocus(ev) && dynamicCanvas && frame->GetWindow(ev)->IsActive(ev))    // Do not render handles for print / print preview
  247.         fDrawFrame->GetSelection(ev)->RenderSelectionHandles(ev, vc, fDrawFrame->GetZoomFactor());
  248. }
  249.  
  250. //----------------------------------------------------------------------------------------
  251. //    CDrawView::InternalTransformChanged
  252. //----------------------------------------------------------------------------------------
  253.  
  254. void CDrawView::InternalTransformChanged(Environment *ev)
  255. {
  256.     // InternalTransformChanged can be called before fDrawPart as been initialized
  257.     if (fDrawPart != NULL)
  258.     {
  259.         // ----- Set purgeable flag according to visibility -----
  260.         FW_CRect bounds = GetBoundsInContent(ev);
  261.         CDrawContentShapeIterator ite(fDrawPart->GetDrawContent());
  262.         for (CBaseShape* theShape = ite.First(); ite.IsNotComplete(); theShape = ite.Next())
  263.             theShape->MakePurgeable(ev, fDrawFrame, bounds);
  264.  
  265.         CDrawFacetClipper facetClipper(fDrawPart);
  266.         facetClipper.Clip(ev, fDrawFrame->GetPresentation(ev), NULL);
  267.     }
  268. }
  269.  
  270. //----------------------------------------------------------------------------------------
  271. // CDrawView::AdjustToNewLayout
  272. //----------------------------------------------------------------------------------------
  273.  
  274. void CDrawView::AdjustToNewLayout(Environment *ev, 
  275.                                 const FW_CPoint& oldExtent, 
  276.                                 const FW_CPoint& newExtent, 
  277.                                 FW_ERedrawVerb redraw)
  278. {
  279. FW_UNUSED(oldExtent);
  280. FW_UNUSED(newExtent);
  281.  
  282.     fDrawFrame->AdjustContentViewSize(ev, redraw);
  283. }
  284.     
  285. //----------------------------------------------------------------------------------------
  286. // CDrawView::AdjustCursor
  287. //----------------------------------------------------------------------------------------
  288.  
  289. FW_Handled CDrawView::AdjustCursor(Environment *ev, ODFacet* facet, const FW_CPoint& where, ODEventInfo* eventInfo)
  290. {
  291.     FW_Handled cursorAdjusted = FW_CView::AdjustCursor(ev, facet, where, eventInfo);
  292.     
  293.     if (cursorAdjusted == FW_kNotHandled && 
  294.         fDrawPart->GetLastActiveFrame(ev) == (FW_CFrame*)fDrawFrame && 
  295.             fDrawPart->GetTool() != kSelectTool)
  296.     {
  297.         FW_gCrossHairCursor.Select();
  298.         cursorAdjusted = FW_kHandled;
  299.     }
  300.  
  301.     return cursorAdjusted;
  302. }
  303.  
  304. //----------------------------------------------------------------------------------------
  305. //    CDrawView::DoVirtualKey
  306. //----------------------------------------------------------------------------------------
  307.  
  308. FW_Handled CDrawView::DoVirtualKey(Environment* ev, const FW_CVirtualKeyEvent& theVirtualKeyEvent)
  309. {    
  310.     FW_Handled wasHandled = FW_kNotHandled;
  311.     
  312.     switch (theVirtualKeyEvent.GetKeyCode(ev))
  313.     {
  314.         case FW_kVKBackspace:
  315.         case FW_kVKClear:
  316.             if (!fDrawFrame->GetSelection(ev)->IsEmpty(ev))
  317.             {
  318.                 FW_CClipboardCommand* cmd = GetFrame(ev)->NewClipboardCommand(ev, kODCommandClear);
  319.                 if (cmd)
  320.                 {
  321.                     cmd->Execute(ev);
  322.                     wasHandled = FW_kHandled;
  323.                 }
  324.             }
  325.             break;
  326.     }
  327.  
  328.     return wasHandled;
  329. }
  330.  
  331. //----------------------------------------------------------------------------------------
  332. // CDrawView::WantsToBeTarget: 
  333. //----------------------------------------------------------------------------------------
  334.  
  335. FW_Boolean CDrawView::WantsToBeTarget(Environment* ev)
  336. {
  337. FW_UNUSED(ev);
  338.     return TRUE;
  339. }
  340.  
  341. //----------------------------------------------------------------------------------------
  342. // CDrawView::DoMouseDown
  343. //----------------------------------------------------------------------------------------
  344.  
  345. FW_Handled CDrawView::DoMouseDown(Environment *ev, const FW_CMouseEvent& theMouseEvent)
  346. {
  347.     ODFacet*         theFacet = theMouseEvent.GetFacet(ev);
  348.     CDrawSelection*    selection = fDrawFrame->GetSelection(ev);
  349.     
  350.     if (fDrawPart->GetTool() == kSelectTool)
  351.     {
  352.         FW_Handled handled = FW_kNotHandled;
  353.         
  354.         if (selection->IsMouseInDraggableItem(ev, fDrawFrame, theMouseEvent, FALSE))
  355.         {
  356.             if (fDrawFrame->Drag(ev, theMouseEvent))
  357.                 handled = FW_kHandled;
  358.         }
  359.         else if (!selection->Resize(ev, theMouseEvent))
  360.         {
  361.             selection->SelectWithRectangle(ev, theMouseEvent);
  362.             handled = FW_kHandled;
  363.         }
  364.                             
  365.         return handled;
  366.     }
  367.     
  368.     // ----- If read only don't want to create a new shape -----
  369.     if (fDrawPart->IsReadOnly(ev))
  370.     {
  371.         FW_Beep();
  372.         return FW_kHandled;
  373.     }
  374.     
  375.     // ----- Create a new shape -----
  376.     CBaseShape *theShape =  fDrawPartContent->NewShape(ev, fDrawPart->GetTool() - kLine + kLineShape);
  377.     
  378.     FW_TRY
  379.     {
  380.         FW_CStyle trackStyle(fDrawPart->GetRenderVerb() == kFillOnly ? FW_kFixedPos1 : fDrawPart->GetPenSize(), FW_kGrayPat);
  381.         FW_CInk trackInk(FW_kRGBBlack, FW_kRGBWhite, FW_kXOr);
  382.         theShape->ChangeRenderVerb(ev, kFrameOnly);
  383.         theShape->SetFrameInk(trackInk);
  384.         theShape->SetFrameStyle(trackStyle);
  385.         
  386.         CShapeTracker tracker(ev, this, theFacet, theShape, fDrawPart->IsAutoGridOn());
  387.         if (tracker.Track(ev, theMouseEvent))
  388.         {
  389.             
  390.             CDrawShapeCommand* cmd = FW_NEW(CDrawShapeCommand,
  391.                                             (ev, fDrawPart, fDrawFrame, selection, theShape));
  392.             if (cmd->Execute(ev))
  393.             {
  394.                 theShape->SetFrameInk(FW_kNormalInk);
  395.                 theShape->SetFrameStyle(FW_kNormalStyle);
  396.                 
  397.                 FW_CColor color;
  398.         
  399.                 theShape->ChangeRenderVerb(ev, fDrawPart->GetRenderVerb());
  400.                 theShape->ChangePenSize(ev, fDrawPart->GetPenSize());
  401.                         
  402.                 fDrawPart->GetFrameColor(color);
  403.                 theShape->ChangeFrameColor(ev, color);
  404.         
  405.                 fDrawPart->GetFillColor(color);
  406.                 theShape->ChangeFillColor(ev, color);
  407.         
  408.                 theShape->ChangeFramePattern(ev, fDrawPart->GetFramePattern());
  409.                 theShape->ChangeFillPattern(ev, fDrawPart->GetFillPattern());
  410.                 
  411.                 FW_CRect dragRect;
  412.                 theShape->GetDragRect(dragRect);
  413.     
  414.                 FW_CAcquiredODShape aqShape = ::FW_NewODShape(ev, dragRect);
  415.                 
  416.                 CDrawFacetClipper facetClipper(fDrawPart);
  417.                 facetClipper.Clip(ev, fDrawFrame->GetPresentation(ev), aqShape);
  418.                 
  419.                 FW_CViewContext vc(ev, this, theMouseEvent.GetFacet(ev));
  420.                 theShape->RenderShape(ev, theFacet, vc);
  421.                 
  422.                 theShape->GetUpdateBox(ev, aqShape);
  423.                 Invalidate(ev, aqShape, TRUE);        // want to invalidate all frames
  424.                 
  425.                 // ----- Because drawing has already been done in this facet -----
  426.                 ViewContentToFrame(ev, aqShape);
  427.                 theFacet->Validate(ev, aqShape, NULL);
  428.             }
  429.             else
  430.                 delete theShape;
  431.         }
  432.         else
  433.         {
  434.             delete theShape;
  435.         }
  436.     }
  437.     FW_CATCH_BEGIN
  438.     FW_CATCH_EVERYTHING()
  439.     {
  440.         delete theShape;
  441.         FW_THROW_SAME();
  442.     }
  443.     FW_CATCH_END
  444.     
  445.     return FW_kHandled;
  446. }
  447.  
  448. //----------------------------------------------------------------------------------------
  449. // CDrawView::DrawGrid
  450. //----------------------------------------------------------------------------------------
  451.  
  452. void CDrawView::DrawGrid(Environment *ev, FW_CGraphicContext& gc, const FW_CRect& invalidRect)
  453. {
  454. FW_UNUSED(ev);
  455.     if (fDrawFrame->IsGraphicsGridOn())
  456.     {
  457.         FW_BitPattern vertical = {0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  458.         FW_BitPattern horizontal = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80};
  459.         FW_CPattern verticalPat(vertical);
  460.         FW_CPattern horizontalPat(horizontal);
  461.         
  462.         FW_Fixed minY = FW_IntToFixed(72 * (FW_FixedToInt(invalidRect.top) / 72));
  463.         FW_Fixed maxY = FW_IntToFixed(72 * (FW_FixedToInt(invalidRect.bottom + FW_kFixed72) / 72));
  464.         FW_Fixed minX = FW_IntToFixed(72 * (FW_FixedToInt(invalidRect.left) / 72));
  465.         FW_Fixed maxX = FW_IntToFixed(72 * (FW_FixedToInt(invalidRect.right + FW_kFixed72) / 72));
  466.  
  467.         // skip top-most and left-most lines
  468.         FW_Fixed startX = (minX == FW_kFixed0) ? FW_kFixed72 : minX;
  469.         FW_Fixed startY = (minY == FW_kFixed0) ? FW_kFixed72 : minY;
  470.         
  471.         FW_CStyle lineStyle(FW_kFixed0, verticalPat);
  472.         FW_CLineShape line(startX, minY, startX, maxY, FW_kNormalInk, lineStyle);
  473.  
  474.         for (FW_Fixed x = startX; x <= maxX; x += FW_kFixed72)
  475.         {
  476.             line.Render(gc);
  477.             line.MoveShape(FW_kFixed72, FW_kFixed0);
  478.         }
  479.         
  480.         line.GetStyle().SetPattern(horizontalPat);
  481.         line.SetLineStart(minX, startY);
  482.         line.SetLineEnd(maxX, startY);
  483.         
  484.         for (FW_Fixed y = startY; y <= maxY; y += FW_kFixed72)
  485.         {
  486.             line.Render(gc);
  487.             line.MoveShape(FW_kFixed0, FW_kFixed72);
  488.         }
  489.     }
  490. }
  491.  
  492. //----------------------------------------------------------------------------------------
  493. // CDrawView::SizeChanged
  494. //----------------------------------------------------------------------------------------
  495. //    My content view size has changed I need to clip my embedded facets. It's better to do it
  496. //    here than in CDrawFrame::FrameShapeChanged because my frame shape can be changing but
  497. //    my bounds may not.
  498.  
  499. void CDrawView::SizeChanged(Environment* ev, const FW_CPoint& oldSize)
  500. {
  501.     FW_CSuperView::SizeChanged(ev, oldSize);
  502.     
  503.     // ----- Reclip -----
  504.     CDrawFacetClipper facetClipper(fDrawPart);
  505.     facetClipper.Clip(ev, fDrawFrame->GetPresentation(ev));
  506.     
  507.     // ----- Set purgeable flag according to visibility -----
  508.     FW_CRect bounds = GetBoundsInContent(ev);
  509.     CDrawContentShapeIterator ite(fDrawPartContent);
  510.     for (CBaseShape* theShape = ite.First(); ite.IsNotComplete(); theShape = ite.Next())
  511.         theShape->MakePurgeable(ev, fDrawFrame, bounds);
  512. }
  513.  
  514. //----------------------------------------------------------------------------------------
  515. //    CDrawView::Create
  516. //----------------------------------------------------------------------------------------
  517.  
  518. void* CDrawView::Create(FW_CReadableStream& stream, FW_ClassTypeConstant type)
  519. {
  520. FW_UNUSED(stream);
  521. FW_UNUSED(type);
  522.     FW_SOMEnvironment ev;
  523.     return new CDrawView(ev);
  524. }
  525.  
  526. //----------------------------------------------------------------------------------------
  527. //    CDrawView::Destroy
  528. //----------------------------------------------------------------------------------------
  529.  
  530. void CDrawView::Destroy(void* object, FW_ClassTypeConstant type)
  531. {
  532. FW_UNUSED(type);
  533.     CDrawView* self = (CDrawView*) object;
  534.     delete self;
  535. }
  536.  
  537. //----------------------------------------------------------------------------------------
  538. //    CDrawView::Flatten
  539. //----------------------------------------------------------------------------------------
  540.  
  541. void CDrawView::Flatten(Environment* ev, FW_CWritableStream& archive) const
  542. {
  543.     FW_CSuperView::Flatten(ev, archive);
  544. }
  545.  
  546. //----------------------------------------------------------------------------------------
  547. //    CDrawView::InitializeFromStream
  548. //----------------------------------------------------------------------------------------
  549.  
  550. void CDrawView::InitializeFromStream(Environment* ev, FW_CReadableStream& stream)
  551. {
  552.     FW_CSuperView::InitializeFromStream(ev, stream);
  553.     
  554.     FW_OObjectRegistry*    registry = stream.GetRegistry();
  555.     FW_CFrame* frame = (FW_CFrame*) registry->LookupByID(ev, FW_kPreregisteredFrameObject);
  556.     FW_ASSERT(frame != NULL);
  557.     
  558.     fDrawFrame = FW_DYNAMIC_CAST(CDrawFrame, frame);
  559.     FW_ASSERT(fDrawFrame != NULL);
  560.     
  561.     FW_CEmbeddingPart* part = fDrawFrame->GetPart(ev);
  562.     fDrawPart = FW_DYNAMIC_CAST(CDrawPart, part);
  563.     FW_ASSERT(fDrawPart != NULL);
  564.  
  565.     fDrawPartContent = fDrawPart->GetDrawContent();
  566.     FW_ASSERT(fDrawPartContent != NULL);
  567. }
  568.  
  569.